package com.crrc.sandameter.view

import android.annotation.SuppressLint
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.view.View
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.cj.mvvmlib.base.activity.BaseVmActivity
import com.cj.mvvmlib.ext.util.GsonInstance
import com.cj.mvvmlib.util.ToastUtil
import com.crrc.sandameter.Constant
import com.crrc.sandameter.DeviceManager
import com.crrc.sandameter.DialogUtils
import com.crrc.sandameter.common.LogFileUtils
import com.crrc.sandameter.common.RecyclerItemDecoration
import com.crrc.sandameter.common.SPUtil
import com.crrc.sandameter.databinding.ActivityDataCollectionBinding
import com.crrc.sandameter.device.COMUtil
import com.crrc.sandameter.device.REGISTER_ADD
import com.crrc.sandameter.entity.DebugProceOneEnum
import com.crrc.sandameter.entity.SubtaskList
import com.crrc.sandameter.entity.TaskEntity
import com.crrc.sandameter.entity.TaskSubmitModel
import com.crrc.sandameter.http.API
import com.crrc.sandameter.http.GET
import com.crrc.sandameter.http.RequestBean
import com.crrc.sandameter.http.http
import com.crrc.sandameter.http.parseObject
import com.crrc.sandameter.vm.DataCollectionViewModel
import org.json.JSONObject
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import java.util.Random
import kotlin.math.abs


/**
 * 数据采集页面
 */
class DataCollectionActivity : BaseVmActivity<DataCollectionViewModel>() {

    private lateinit var dataCollectionBinding: ActivityDataCollectionBinding
    private var tableAdapter: TableAdapter? = null
    private val currentInterval = 50L // 打点间隔时间
    private var currentweight = "0"
    private var weightResult = 0.0
    private var layoutManager: GridLayoutManager? = null
    private val positionNames = mutableListOf<TableItem.RowHeader>()
    private val taskEntityList = mutableListOf<TaskEntity>()

    // 用于解决滚动卡顿的标志位
    private var isFixedColumnScrolling = false
    private var isScrollableTableScrolling = false
    override fun useTitleBar(): Boolean {
        return false
    }

    // 示例：可以根据实际获取的列车车厢号来填充
    private val trainCarNumbers = mutableListOf<String>()

    // 准备 RecyclerView 的数据列表
    private val tableItems = mutableListOf<TableItem>()

    //左侧列表数据
    private val leftTableItems = mutableListOf<TableItem>()

    override fun layoutId(): View {
        dataCollectionBinding = ActivityDataCollectionBinding.inflate(layoutInflater)
        return dataCollectionBinding.root
    }

    override fun initView(savedInstanceState: Bundle?) {
        handler.postDelayed(tickRunnable, currentInterval)
    }

    override fun initData() {
        getTaskList()
    }

    @SuppressLint("SetTextI18n")
    private fun initUi(taskEntity: TaskEntity) {
        dataCollectionBinding.trainNumberTv.text = "列车号：${taskEntity.trainCode}"
        dataCollectionBinding.trainListRv.layoutManager = LinearLayoutManager(this)
        dataCollectionBinding.trainListRv.adapter = TaskEntityListAdapter(taskEntityList) {
            dataCollectionBinding.trainNumberTv.text = "列车号：${it.trainCode}"
            trainCarNumbers.clear()
            val vehicleNames =
                if (it.debugProceOne == DebugProceOneEnum.单元调试1.value || it.debugProceOne == DebugProceOneEnum.单元调试2.value) {
                    it.vehicleName ?: ""
                } else {
                    it.projectVehicleName
                }
            trainCarNumbers.addAll(createTrainCarNumbers(vehicleNames))
            layoutManager?.spanCount = trainCarNumbers.size
            findSgTaskDetail(it.items[0].sgItemId.toString())
        }

        // 计算总列数 (行标题列 + 动态车号列数)
        val totalColumnCount = trainCarNumbers.size

        // 设置 GridLayoutManager
        layoutManager = GridLayoutManager(this, totalColumnCount)
        val leftLayoutManager = LinearLayoutManager(this)
        dataCollectionBinding.leftRv.layoutManager = leftLayoutManager
        dataCollectionBinding.leftRv.addItemDecoration(RecyclerItemDecoration(2, 2, 2, 2))
        dataCollectionBinding.leftRv.adapter =
            TableAdapter(leftTableItems, object : TableAdapter.OnItemClickListener {
                override fun onDataCellClick(adapterPosition: Int, data: TableItem) {
                }
            })

        // SpanSizeLookup 保持不变，因为每个单元格仍然占用1个span
        layoutManager?.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
            override fun getSpanSize(position: Int): Int {
                return 1
            }
        }

        dataCollectionBinding.checkListRv.layoutManager = layoutManager
        dataCollectionBinding.checkListRv.addItemDecoration(RecyclerItemDecoration(2, 2, 2, 2))
        tableAdapter = TableAdapter(tableItems, object : TableAdapter.OnItemClickListener {
            override fun onDataCellClick(adapterPosition: Int, data: TableItem) { // 计算行索引和列索引
                if (data is TableItem.DataCell) {
                    val clickedPositionName =
                        positionNames.find { it.artStepId == data.artStepId }?.position ?: ""
                    DialogUtils.showDialog(this@DataCollectionActivity,
                        data.vhecileNo,
                        clickedPositionName,
                        currentweight,
                        {
                            data.testValue = currentweight
                            data.operateResult = currentweight
                            data.deviceNo = "B9-7F-C4-31-A5-39"
                            data.operatePerson = SPUtil.get(Constant.userName, "").toString()
                            data.operatePersonName = SPUtil.get(Constant.userName, "").toString()
                            data.operateTime = convertTimestampToString(System.currentTimeMillis())
                            submitCheckResult(data, adapterPosition)
                        })
                }
            }
        })
        dataCollectionBinding.checkListRv.adapter = tableAdapter
    }

    @SuppressLint("NotifyDataSetChanged")
    private fun createData(data: List<SubtaskList>) { // 动态的车号数据 (列标题)
        leftTableItems.clear()
        tableItems.clear() // --- 第一行：左上角特殊单元格 + 动态车号标题 ---
        leftTableItems.add(TableItem.CrossedCell) // 左上角单元格

        trainCarNumbers.forEach {
            tableItems.add(TableItem.ColumnHeader(it)) // 添加列车编号
        }

        // --- 剩余行：每个位置的标题 + 对应车号下的检查数据 ---0
        for (posIndex in positionNames.indices) {
            val positionName = positionNames[posIndex]
            leftTableItems.add(positionName) // 添加当前位置的行标题
            val locationList = data[posIndex].locationList
            locationList.forEach {
                it.artStepId = positionName.artStepId
            }
            tableItems.addAll(locationList)
        }
        dataCollectionBinding.leftRv.adapter?.notifyDataSetChanged()
        dataCollectionBinding.checkListRv.adapter?.notifyDataSetChanged()
    }

    override fun setListener() {
        dataCollectionBinding.refreshIv.setOnClickListener {
            getTaskList()
        }
        dataCollectionBinding.peelBt.setOnClickListener {
            DeviceManager.zeroDevice(0)
        } // --- 同步垂直滚动，优化卡顿问题 ---
        dataCollectionBinding.leftRv.addOnScrollListener(object : RecyclerView.OnScrollListener() {
            override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
                super.onScrollStateChanged(recyclerView, newState) // 当固定列开始滚动时，设置标志位
                if (newState == RecyclerView.SCROLL_STATE_DRAGGING || newState == RecyclerView.SCROLL_STATE_SETTLING) {
                    isFixedColumnScrolling = true
                } else if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                    isFixedColumnScrolling = false
                }
            }

            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                super.onScrolled(recyclerView, dx, dy) // 只有当可滚动表格没有主动滚动时，才同步滚动
                if (!isScrollableTableScrolling) {
                    dataCollectionBinding.checkListRv.scrollBy(0, dy)
                }
            }
        })

        dataCollectionBinding.checkListRv.addOnScrollListener(object :
            RecyclerView.OnScrollListener() {
            override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
                super.onScrollStateChanged(recyclerView, newState) // 当可滚动表格开始滚动时，设置标志位
                if (newState == RecyclerView.SCROLL_STATE_DRAGGING || newState == RecyclerView.SCROLL_STATE_SETTLING) {
                    isScrollableTableScrolling = true
                } else if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                    isScrollableTableScrolling = false
                }
            }

            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                super.onScrolled(recyclerView, dx, dy) // 只有当固定列没有主动滚动时，才同步滚动
                if (!isFixedColumnScrolling) {
                    dataCollectionBinding.leftRv.scrollBy(0, dy)
                }
            }
        })
    }

    @SuppressLint("SetTextI18n")
    override fun createObserver() {
        DeviceManager.deviceData.observe(this) {
            val functionCode = it.substring(0, 4)
            if (functionCode == REGISTER_ADD.WEIGHT_VALUE) {
                dismissLoadingDialog()
                val weight = divideByTen(COMUtil.decodeHEX(it.substring(10, 18)))
                val value = abs(weightResult - weight)
                if (value > 0.5) {
                    weightResult = weight
                    currentweight = when {
                        weight < 5 && weight > 0 -> {
                            "0"
                        }

                        weight > -5 && weight < 0 -> {
                            "0"
                        }

                        else -> {
                            "${correctNumber(weight)}.${getRandomNumber()}"
                        }
                    }
                    dataCollectionBinding.currentWeightTv.text = "${currentweight}g"
                }
            }
        }
    }

    // 使用主线程的 Handler
    private val handler = Handler(Looper.getMainLooper())

    // 打点任务的 Runnable
    private val tickRunnable = object : Runnable {
        override fun run() {
            DeviceManager.getWeight()
            handler.postDelayed(this, currentInterval)
        }
    }

    /**
     * 获取任务列表
     */
    @SuppressLint("NotifyDataSetChanged")
    private fun getTaskList() {
        showLoadingDialog("任务获取中...")
        http {
            url = API.getBaseUrl() + API.TASK_LIST
            requestType = GET
            paramters["authNo"] = SPUtil.get(Constant.authNo, "").toString()
            paramters["userName"] = SPUtil.get(Constant.account, "").toString()
            success = {
                dismissLoadingDialog()
                val taskList = parseObject<RequestBean<List<TaskEntity>>>(it).data
                if (taskList?.isNotEmpty() == true) {
                    taskEntityList.clear()
                    taskEntityList.addAll(taskList)
                    val taskEntity = taskEntityList[0]
                    taskEntity.isSeleted = true
                    val items = taskList[0].items
                    trainCarNumbers.clear()
                    val vehicleNames =
                        if (taskList[0].debugProceOne == DebugProceOneEnum.单元调试1.value || taskList[0].debugProceOne == DebugProceOneEnum.单元调试2.value) {
                            taskList[0].vehicleName ?: ""
                        } else {
                            taskList[0].projectVehicleName
                        }
                    trainCarNumbers.addAll(createTrainCarNumbers(vehicleNames))
                    initUi(taskEntity)
                    if (items.isNotEmpty()) {
                        val item = items[0]
                        findSgTaskDetail(item.sgItemId.toString())
                    }
                }
                LogFileUtils.writeTxtToFile("获取任务列表返回数据：$it")
            }
            fail = { code, message ->
                dismissLoadingDialog()
                ToastUtil.showShortToast("获取任务失败：$code-$message")
            }
        }
    }

    /**
     * 获取任务详情
     */
    private fun findSgTaskDetail(sgItemId: String) {
        showLoadingDialog("任务详情获取中...")
        http {
            url = API.getBaseUrl() + API.TASK_DETAIL
            requestType = GET
            paramters["authNo"] = SPUtil.get(Constant.authNo, "").toString()
            paramters["sgItemId"] = sgItemId
            success = {
                dismissLoadingDialog()
                val taskDetailList = parseObject<RequestBean<List<SubtaskList>>>(it).data
                taskDetailList?.let { detail ->
                    createPositionNames(taskDetailList)
                    createData(detail)
                }
            }
            fail = { code, message ->
                dismissLoadingDialog()
                ToastUtil.showShortToast("获取子任务失败：$code-$message")
            }
        }
    }

    private fun divideByTen(number: Long): Double {
        val result = number.toDouble() / 10.0 //因为标定和满量程都是乘以10，所以实际结果要除以10
        return String.format("%.1f", result).toDouble()
    }

    /**
     * 提取位置和标准值
     */
    private fun extractSandSpreadingData(stepStandard: String,
        stepStandardSignalValue: String): String {

        val numberRegex = Regex("""(\d+g/\d+s)""")
        val valueRegex = Regex("""<(\d+),(\d+)>""")
        val positionRegex = Regex("""<(\d+),(\d+)>""")

        val numberMatch = numberRegex.find(stepStandard)
        val positionMatch = positionRegex.find(stepStandard)
        val valueMatch = valueRegex.find(stepStandardSignalValue)

        val numericalPart = numberMatch?.groups?.get(1)?.value

        var formattedPosition: String? = null
        var valueString: String? = null
        if (positionMatch != null) {
            val axis = positionMatch.groups[1]?.value
            val position = positionMatch.groups[2]?.value
            if (axis != null && position != null) {
                formattedPosition = "${axis}轴${position}位"
            }
        }
        if (valueMatch != null) {
            val value1 = valueMatch.groups[1]?.value
            val value2 = valueMatch.groups[2]?.value
            if (value1 != null && value2 != null) {
                valueString = "${value1}-${value2}g"
            }
        }
        return "$formattedPosition(${valueString})"
    }

    /**
     * 创建位置数据
     */
    private fun createPositionNames(taskDetailList: List<SubtaskList>) {
        positionNames.clear()
        taskDetailList.forEach {
            positionNames.add(TableItem.RowHeader(extractSandSpreadingData(it.stepStandard,
                it.stepStandardSignalValue), it.artStepId))
        }
    }

    /**
     * 创建车厢编号
     */
    private fun createTrainCarNumbers(trainNumber: String): MutableList<String> {
        return trainNumber.split(",").toMutableList()
    }

    /**
     * 提交检测结果
     */
    private fun submitCheckResult(entity: TableItem.DataCell, adapterPosition: Int) {
        http {
            url = API.getBaseUrl() + API.TASK_SUBMIT
            body = createRequestJson(entity)
            success = {
                tableAdapter?.updateDataCell(entity, adapterPosition, "检（${currentweight}g）")
                ToastUtil.showShortToast("提交成功")
            }
            fail = { code, message ->
                ToastUtil.showShortToast("提交失败：$code-$message")
            }
        }
    }

    /**
     * 创建请求体
     */
    private fun createRequestJson(entity: TableItem.DataCell): JSONObject {
        val authNo = SPUtil.get(Constant.authNo, "").toString()
        val requestBean = TaskSubmitModel(authNo,
            entity.taskId,
            entity.sgItemId,
            entity.operatePersonName,
            listOf(entity))
        val dataJson = GsonInstance.getInstance().gson.toJson(requestBean)
        return JSONObject(dataJson)
    }

    fun convertTimestampToString(timestamp: Long): String {
        val sdf: SimpleDateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
        val date: Date = Date(timestamp)
        return sdf.format(date)
    }

    /**
     * 获取1-5的随机数
     */
    private fun getRandomNumber(): Int {
        val random = Random()
        return random.nextInt(5) + 1
    }

    /**
     * 修正数字
     */
    private fun correctNumber(number: Double): Int { // 定义需要比较的整数列表
        val targets = listOf(1000, 2000, 3000, 4000, 5000, 6000)

        // 遍历目标整数
        for (target in targets) { // 计算当前数字与目标整数之间的差值
            val difference = abs(number - target)

            // 判断差值是否小于或等于 5
            if (difference <= 5) { // 如果是，返回目标整数
                return target
            }
        }

        // 如果没有找到匹配项，返回原始数字
        return number.toInt()
    }
}